package org.mybatis.generator.api.plus;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.TopLevelClass;

import java.io.*;
import java.util.Iterator;
import java.util.List;

/**
 * @author wangfupeng
 */
public class MybatisUtilBatchMapper {

    public static void writeBatchMapper(String basePackageName, String aspectPackageName, String targetProject, TopLevelClass topLevelClass, IntrospectedTable introspectedTable, String tableName, String mapperPackage, String modelPackage) {
        File file = null;
        OutputStream fileOutputStream = null;
        BufferedWriter bufferedWriter = null;
        try {
            String packageNameFolder = mapperPackage.replaceAll("\\.", "/");
            targetProject = targetProject.replaceAll("\\./", "");
            File folder = new File(targetProject + "/" + packageNameFolder + "/batch");
            folder.mkdirs();
            file = new File(targetProject + "/" + packageNameFolder + "/batch/Batch" + tableName + "Mapper.java");
            //如果文件不存在，则创建文件，如果已存在，则覆盖
            file.createNewFile();
            fileOutputStream = new FileOutputStream(file);
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream, "utf-8"));
            bufferedWriter.write("package " + mapperPackage+".batch;\n" +
                    "\n" +
                    "import " + modelPackage+"." + tableName + ";\n");
            bufferedWriter.write("import org.apache.ibatis.annotations.Mapper;\n" +
                    "import org.apache.ibatis.annotations.Insert;\n" +
                    "import org.springframework.context.annotation.Lazy;\n" +
                    "import org.apache.ibatis.annotations.Param;\n" +
                    "\n" +
                    "import java.util.List;\n" +
                    "import java.util.Date;\n" +
                    "\n" +
                    "/*" + introspectedTable.getRemarks() + "的集体插入*/\n" +
                    "@Lazy\n" +
                    "@Mapper\n" +
                    "public interface Batch" + tableName + "Mapper {\n" +
                    "    \n");

            List<IntrospectedColumn> introspectedColumns = introspectedTable.getAllColumns();
            Iterator<IntrospectedColumn> iterator = introspectedColumns.iterator();
            while (iterator.hasNext()) {
                IntrospectedColumn introspectedColumn = iterator.next();
                String columnName = introspectedColumn.getJavaProperty();
            }
            bufferedWriter.write("    @Insert(\"<script>\" +\n" +
                    "            \"    insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime() + " (");
            Iterator<IntrospectedColumn> iteratorInsertInto = introspectedColumns.iterator();
            String insertIntoString = "";
            while (iteratorInsertInto.hasNext()) {
                IntrospectedColumn introspectedColumn = iteratorInsertInto.next();
                String columnName = introspectedColumn.getActualColumnName();
                insertIntoString += (columnName + ",");
            }
            insertIntoString = insertIntoString.substring(0, insertIntoString.length() - 1);
            bufferedWriter.write(insertIntoString);
            bufferedWriter.write(")\\n\" +\n" +
                    "            \"    values \" +\n" +
                    "            \"<foreach item='item' index='index' collection='" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(tableName) + "s' open='(' separator='), (' close=')'>\" +\n");
            //"            \"    #{item.username,jdbcType=VARCHAR}, #{item.password,jdbcType=VARCHAR}, #{item.createTime,jdbcType=TIMESTAMP},#{item.updateTime,jdbcType=TIMESTAMP}\" +\n" +

            Iterator<IntrospectedColumn> iteratorColumns = introspectedColumns.iterator();
            String iteratorColumnsString = "               \"";
            while (iteratorColumns.hasNext()) {
                IntrospectedColumn introspectedColumn = iteratorColumns.next();
                String columnName = introspectedColumn.getJavaProperty();
                iteratorColumnsString += "#{item." + columnName + ",jdbcType=";
                FullyQualifiedJavaType fullyQualifiedJavaType = introspectedColumn
                        .getFullyQualifiedJavaType();
//                String fullyQualifiedName = fullyQualifiedJavaType.getFullyQualifiedName();
                if (fullyQualifiedJavaType.isPrimitive()) {
                    if ("boolean".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("BOOLEAN");
                    } else if ("byte".equals(fullyQualifiedJavaType.getFullyQualifiedName())
                            || "int".equals(fullyQualifiedJavaType.getFullyQualifiedName())
                            || "short".equals(fullyQualifiedJavaType.getFullyQualifiedName())
                    ) {
                        iteratorColumnsString += ("INTEGER");
                    } else if ("double".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("DOUBLE");
                    } else if ("float".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("DOUBLE");
                    } else if ("long".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("BIGINT");
                    } else {
                        iteratorColumnsString += ("VARCHAR");
                    }
                } else {
                    if ("java.lang.Boolean".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("BOOLEAN");
                    } else if ("java.lang.Byte".equals(fullyQualifiedJavaType.getFullyQualifiedName())
                            || "java.lang.Integer".equals(fullyQualifiedJavaType.getFullyQualifiedName())
                            || "java.lang.Short".equals(fullyQualifiedJavaType.getFullyQualifiedName())
                    ) {
                        iteratorColumnsString += ("INTEGER");
                    } else if ("java.lang.Double".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("DOUBLE");
                    } else if ("java.lang.Float".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("DOUBLE");
                    } else if ("java.lang.Long".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("BIGINT");
                    } else if ("java.lang.BigDecimal".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("BIGINT");
                    } else if ("java.lang.String".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("VARCHAR");
                    } else if ("java.util.Date".equals(fullyQualifiedJavaType.getFullyQualifiedName())) {
                        iteratorColumnsString += ("TIMESTAMP");
                    } else {
                        iteratorColumnsString += ("VARCHAR");
                    }
                }
                iteratorColumnsString += "},";
            }
            iteratorColumnsString = iteratorColumnsString.substring(0, iteratorColumnsString.length() - 1);
            bufferedWriter.write(iteratorColumnsString + "\"+\n");

            bufferedWriter.write("            \"</foreach>\" +\n" +
                    "            \"</script>\")\n");
            bufferedWriter.write("    public Integer batchAdd(" +
                    "@Param(value=\"" + MybatisUtilCommon.toLowerCaseAtFirstCharacter(tableName) + "s\") " +
                    "List<" + tableName + "> " + MybatisUtilCommon.toLowerCaseAtFirstCharacter(tableName) + "s);\n" +
                    "\n");
            bufferedWriter.write("    \n" + "}");
            bufferedWriter.write("\n");
            System.out.println("write to file success : " + file.getPath());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MybatisUtilCommon.closeBufferWriterAndFileOutputStream(fileOutputStream, bufferedWriter);
        }
    }

}
